import { EntityManager } from "../../Base/EntityManager";
import { G, StateTypeEnum, vecToAngel } from "../../Common";
import { WeaponStateMachine } from "./WeaponStateMachine";
import { IEnemy, IWeapon } from "../../Common/Interface/State";
import DataManager from "../../Runtime/DataManager";
import { IVec2, Node, Sprite, find, tween } from "cc";
import ResourcesManager from "../../Runtime/ResourcesManager";
import { EntityShadeColor, addGunFire } from "../../Runtime/MainManager";
import { MaterialEnum } from "../../Enum";
import Mp3Manager, { Mp3TypeEnum } from "../../Runtime/Mp3Manager";

type tempArg = { color?: any, direction?: IVec2, state?: StateTypeEnum }
export class WeaponManager extends EntityManager {

    target: IEnemy
    owner: number
    fireNode: Node
    body: Node
    bodySprite: Sprite
    init(weapon: IWeapon) {

        const {
            entityType,
            position: { x, y },
            owner
        } = weapon

        this.type = entityType
        this.owner = owner

        this.fsm = this.addComponent(WeaponStateMachine)
        this.fsm.init(this)
        this.body = this.node.getChildByName('body')

        const sprite = this.body.getComponent(Sprite)
        this.bodySprite = sprite
        sprite.customMaterial = ResourcesManager.Ins.materialMap.get(MaterialEnum.entityMaterial)

        this.node.setPosition(x, y)
        this.node.setScale(5, 5)

        this.fireNode = find('fire', this.body)

    }

    render(data: IWeapon, dt: number, arg?: tempArg) {
        const { position } = data

        let state = data.state
        let direction = data.direction

        if (arg?.direction) direction = arg.direction
        if (arg?.state) state = arg.state

        let x = direction.x
        let y = direction.y

        let angel = vecToAngel(x, y)

        if (DataManager.Ins.isSingle) {
            this.setWeaponAngel(dt, angel)
        } else {
            tween(this.node)
                .to(0.03, { angle: angel })
                .delay(0)
                .start()
        }
        this.node.setScale(5, Math.abs(angel) < 90 ? 5 : -5)
        this.node.setPosition(position.x, position.y)
        this.state = state
        if (state === StateTypeEnum.shoot) {
            addGunFire(this.fireNode)
            Mp3Manager.Ins.play(Mp3TypeEnum.shoot)
        }

        switch (data.star) {
            case 1:
                this.bodySprite.color = EntityShadeColor.WhiteOutLine
                break;
            case 2:
                this.bodySprite.color = EntityShadeColor.GreenOutLine
                break;
            case 3:
                this.bodySprite.color = EntityShadeColor.BlueOutLine
                break;
            case 4:
                this.bodySprite.color = EntityShadeColor.PurpleOutLine
                break;
            case 5:
                this.bodySprite.color = EntityShadeColor.OrangeOutLine
                break;
            case 6:
                this.bodySprite.color = EntityShadeColor.RedOutLine
                break;

        }

        if (arg?.color) this.bodySprite.color = arg.color

    }

    /** 设置武器方向 */
    setWeaponAngel(dt: number, angel: number) {
        const speed = G.WeaponAngelSpeed * dt

        if ((angel > 0 && this.node.eulerAngles.z > 0) || (angel < 0 && this.node.eulerAngles.z < 0)) {
            if (angel - speed > this.node.eulerAngles.z) {
                angel = this.node.eulerAngles.z + speed / 2
            } else if (angel + speed < this.node.eulerAngles.z) {
                angel = this.node.eulerAngles.z - speed / 2
            }
        } else if (angel > 0 && this.node.eulerAngles.z < 0) {
            if (Math.abs(angel - this.node.eulerAngles.z) > 180) {
                angel = this.node.eulerAngles.z - speed / 2
            } else {
                angel = this.node.eulerAngles.z + speed / 2
            }
        } else if (angel < 0 && this.node.eulerAngles.z > 0) {
            if (Math.abs(angel - this.node.eulerAngles.z) > 180) {
                angel = this.node.eulerAngles.z + speed / 2
            } else {
                angel = this.node.eulerAngles.z - speed / 2
            }
        }

        if (angel > 180) {
            angel -= 360
        } else if (angel < -180) {
            angel += 360
        }

        this.node.setRotationFromEuler(0, 0, angel)
    }
}